package com.blulioncn.matrix.monitoring.controller;


import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.*;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * 日志时时监控功能
 */
@ServerEndpoint(value = "/monitoring/log")
@Component
public class LogMonitoringController extends BaseController {

    //    private static String temp="E:\\log\\shangguigu_netty\\log.sql";
//    /server/tomcat/logs/catalina.out
    private static String temp=File.separator+"server"+File.separator+"tomcat"+File.separator+"logs"+File.separator+"catalina.out";
    //存放所有在线的客户端
    private static Map<String, Session> sessionMap = new ConcurrentHashMap<>();

    private static Map<String, Integer> lengthMap = new ConcurrentHashMap<String, Integer>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        LOG.info("start*********************onOpen()");
        sessionMap.put(session.getId(), session);
        lengthMap.put(session.getId(), 1);
        new Thread(() -> {
            while (sessionMap.get(session.getId()) != null) {
                BufferedReader reader = null;
                try {
                    String filePath = temp;
                    InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath), "GB2312");
                    reader = new BufferedReader(inputStreamReader);
                    if (null != reader){
                        Object[] lines = reader.lines().toArray();
                        Object[] copyOfRange = Arrays.copyOfRange(lines, lengthMap.get(session.getId()), lines.length);
                        lengthMap.put(session.getId(), lines.length);
                        for (Object result : copyOfRange) {
                            sendMessage((String) result,session);
                        }
                        //休眠1秒
                        Thread.sleep(1000);
                    }
                }catch (Exception e) {
//                    LOG.info("e："+e);
                    sendMessage("Monitoring Connection Exception(Exception)："+e,session);
                }finally {
                    if (null != reader){
                        try {
                            reader.close();
                        } catch (IOException ignored) {
//                        LOG.info("ignored："+ignored);
                            sendMessage("Monitoring Connection Exception(IOException)："+ignored,session);
                        }
                    }
                }
            }
        }).start();
        LOG.info("end*********************onOpen()");
    }

    /**
     * 连接关闭调用的方法
     * 实践表明，每次浏览器刷新，session会发生变化(流程为：刷新页面 -连接关闭-开启新的连接)
     */
    @OnClose
    public void onClose(Session session) {
        sessionMap.remove(session.getId());
        sendMessage(session.getId()+"关闭",session);
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message
     *
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        this.sendMessage(message, session);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
        sendMessage("Monitoring Connection Exception(onError)："+error,session);
    }

    /**
     * 发消息
     *
     * @param message 消息内容
     */
    private void sendMessage(String message, Session fromSession) {

        try {
            if (fromSession.isOpen()){
                synchronized (fromSession){
                    fromSession.getBasicRemote().sendText(message);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发消息
     *
     * @param message 消息内容
     */
    private void sendMessage(Object message, Session fromSession) {

        try {
            if (fromSession.isOpen()){
                synchronized (fromSession){
                    fromSession.getBasicRemote().sendObject(message);
                }
            }
        } catch (IOException | EncodeException e) {
            e.printStackTrace();
        }
    }
}
